package com.akcome.apollo.controller;

import java.sql.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.common.utils.bean.AkResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.akcome.apollo.common.AkResultHelper;
import com.akcome.apollo.common.ApolloConstants;
import com.akcome.apollo.common.CommonUtils;
import com.akcome.apollo.common.IpHelper;
import com.akcome.apollo.common.TokenHelper;
import com.akcome.apollo.domain.BmpUser;
import com.akcome.apollo.domain.enums.SmsBusinessTypeEnum;
import com.akcome.apollo.domain.enums.SourceEnum;
import com.akcome.apollo.domain.resultcode.CommonResultCode;
import com.akcome.apollo.domain.resultcode.UserResultCode;
import com.akcome.apollo.service.BmpUserService;
import com.akcome.apollo.service.SmsService;

import io.jsonwebtoken.Claims;

/**
 * 忘记密码
 * @author wn
 *
 */
@Controller
@RequestMapping("/forgotPwd")
public class ForgorPwdController {
	
	@Autowired
	private AkResultHelper akResultHelper;
	
	@Autowired
	private TokenHelper tokenHelper;
	
	@Autowired
	private BmpUserService bmpUserService;
	
	@Autowired
	private SmsService smsService;

	
	/**
     * 忘记密码
     * @return
     */
    @RequestMapping("/")
    public String forgotPwd(){
    	
    	return "noPassword";
    }
    
    /**
     * 验证账户,并发送短信
     * @param email
     * @param imageCode
     * @param request
     * @return
     */
	@ResponseBody
	@RequestMapping("/account")
	public AkResult forgotPwdAccount(String email,String imageCode,HttpServletRequest request,HttpServletResponse response){
		//验证邮箱格式
		if(!CommonUtils.checkEmail(email)){
			return akResultHelper.buildFailAkResult(UserResultCode.EMAIL_ERROR);
		}
		//获取cookies中图片验证码
		String imageCodeText = tokenHelper.getTokenText(ApolloConstants.COOKIE_IMAGE_CODE,request);
		if(StringUtils.isBlank(imageCodeText)){
			//图片验证码已经失效
			return akResultHelper.buildFailAkResult(UserResultCode.IMAGE_CODE_INVALID);

		}
		if(!imageCodeText.toUpperCase().equals(imageCode.toUpperCase())){
			//图片验证码错误
			return akResultHelper.buildFailAkResult(UserResultCode.IMAGE_CODE_FAIL);
		}
		BmpUser bmpUser = bmpUserService.findByEmail(email);
		if(null==bmpUser){
			//用户不存在
			return akResultHelper.buildFailAkResult(UserResultCode.USER_NOT_EXIST);
		}
		String callCode = bmpUser.getCallCode();
		String mobile = bmpUser.getMobile();
		if(StringUtils.isBlank(mobile)){
			//没有绑定手机号
			return akResultHelper.buildFailAkResult(UserResultCode.USER_NOT_BIND_MOBILE);
		}
		//发送短信
		AkResult smsResult = smsService.sendSms(null, callCode, mobile, IpHelper.getIpAddress(request), SourceEnum.WEB.getCode(), SmsBusinessTypeEnum.CAPTCHA.getCode(),request, response);
		if(!CommonResultCode.SUCCESS.getStatusCode().equals(smsResult.getCode())){
			return smsResult;
		}
		
		String token = tokenHelper.generateToken(email+"#"+(System.currentTimeMillis()+180*1000));
		Cookie cookie = new Cookie(ApolloConstants.TOKEN_EMAIL, token);
		cookie.setPath("/");
		response.addCookie(cookie);
		
		return akResultHelper.buildSuccessAkResult(bmpUser.getCallCode()+" "+bmpUser.getMobile().substring(0, 3)+"****"+bmpUser.getMobile().substring(7, 11));
	}
	
	/**
	 * 重新发送短信验证码
	 * @param mobile
	 * @param response
	 * @return
	 */
	@RequestMapping("/sendSms")
	@ResponseBody
	public AkResult sendSms(String email,HttpServletResponse response,HttpServletRequest request){
		String token = "";
		Cookie[] cookies = request.getCookies();
		if(null!=cookies){
			for (Cookie cookie : cookies) {
				if(ApolloConstants.TOKEN_EMAIL.equals(cookie.getName())){
					token = cookie.getValue();
				}
			}
		}
		
		String tokenEmail = tokenHelper.getTextFromToken(token);
		String[] tokenArray =tokenEmail.split("#");
		
		if(StringUtils.isBlank(tokenEmail)){
			//授权失效
			return akResultHelper.buildFailAkResult(CommonResultCode.BAD_REQUEST);

		}
		if(!email.toUpperCase().equals(tokenArray[0].toUpperCase())){
			//授权错误
			return akResultHelper.buildFailAkResult(CommonResultCode.BAD_REQUEST);
		}
		if(Long.parseLong(tokenArray[1])>System.currentTimeMillis()){
			//请求太频繁
			return akResultHelper.buildFailAkResult(UserResultCode.BUSINESS_LIMIT_CONTROL);
		}
		
		BmpUser bmpUser = bmpUserService.findByEmail(email);
		String callCode = bmpUser.getCallCode();
		String mobile = bmpUser.getMobile();
		AkResult result = smsService.sendSms(null, callCode, mobile, IpHelper.getIpAddress(request), SourceEnum.WEB.getCode(), SmsBusinessTypeEnum.CAPTCHA.getCode(),request, response);
		if(CommonResultCode.SUCCESS.getStatusCode().equals(result.getCode())){
			String newToken = tokenHelper.generateToken(email+"#"+(System.currentTimeMillis()+180*1000));
			Cookie cookie = new Cookie(ApolloConstants.TOKEN_EMAIL, newToken);
			cookie.setPath("/");
			response.addCookie(cookie);
		}
		return result;
	}
	
	/**
	 * 验证短信
	 * @param email
	 * @param smsCode
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/sms")
	public AkResult sms(String email,String smsCode,HttpServletRequest request,HttpServletResponse response){
		Claims claims = tokenHelper.getTokenClaims(ApolloConstants.COOKIE_SMS_CODE,request);
		if(null==claims){
			//短信验证码已经失效
			return akResultHelper.buildFailAkResult(UserResultCode.SMS_CODE_INVALID);
		}
		BmpUser bmpUser = bmpUserService.findByEmail(email);
		String callCode = bmpUser.getCallCode();
		String mobile = bmpUser.getMobile();
		if(callCode.equals(claims.get(ApolloConstants.PARAM_CALL_CODE, String.class)) &&
				mobile.equals(claims.get(ApolloConstants.PARAM_MOBILE, String.class)) &&
				smsCode.equals(claims.get(ApolloConstants.PARAM_SMS_CODE, String.class))){
			//短信验证通过
			//更新短信验证码有效期，即密码设置提交的有效期
			Map<String, Object> params = new HashMap<String, Object>();
			params.put(ApolloConstants.PARAM_CALL_CODE, callCode);
			params.put(ApolloConstants.PARAM_MOBILE, mobile);
			params.put(ApolloConstants.PARAM_SMS_CODE, smsCode);
			String token = tokenHelper.generateToken(params);
			Cookie cookie = new Cookie(ApolloConstants.COOKIE_SMS_CODE, token);
			cookie.setMaxAge(tokenHelper.getExpiration());
			cookie.setPath("/");
			response.addCookie(cookie);
			return akResultHelper.buildSuccessAkResult(null);
		}else{
			//短信验证码错误
			return akResultHelper.buildFailAkResult(UserResultCode.SMS_CODE_FAIL);
		}
	}
	
	/**
	 * 更新密码
	 * @param id
	 * @param smsCode
	 * @param password
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/save")
	public AkResult save(String email,String smsCode,String password,String password1, HttpServletRequest request){
		Claims claims = tokenHelper.getTokenClaims(ApolloConstants.COOKIE_SMS_CODE,request);
		if(null==claims){
			//短信验证码已经失效
			return akResultHelper.buildFailAkResult(UserResultCode.SMS_CODE_INVALID);
		}
		//验证密码格式
		if(!CommonUtils.checkPwd(password)){
			return akResultHelper.buildFailAkResult(UserResultCode.PWD_ERROR);
		}
		
		if(!password.equals(password1)){
			return akResultHelper.buildFailAkResult(UserResultCode.NEW_PWD_DIFF);
		}
				
		BmpUser bmpUser = bmpUserService.findByEmail(email);
		String callCode = bmpUser.getCallCode();
		String mobile = bmpUser.getMobile();
		
		if(callCode.equals(claims.get(ApolloConstants.PARAM_CALL_CODE, String.class)) &&
				mobile.equals(claims.get(ApolloConstants.PARAM_MOBILE, String.class)) &&
				smsCode.equals(claims.get(ApolloConstants.PARAM_SMS_CODE, String.class))){
			//短信验证通过
			BCryptPasswordEncoder bc = new BCryptPasswordEncoder(4);
			bmpUser.setPassword(bc.encode(password));
			bmpUserService.save(bmpUser);
			return akResultHelper.buildSuccessAkResult(null);
		}else{
			//短信验证码错误
			return akResultHelper.buildFailAkResult(CommonResultCode.PARAM_ERROR);
		}
	}
}
